package com.frame.pageform;


/**
 * pageForm控制台(中转站)
 */

import java.io.*;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import org.apache.log4j.Logger;
import com.frame.pageform.component.JsonObject;
import com.frame.pageform.logincheck.LoginCheck;
import com.frame.pageform.annotation.Login;

public class PageServlet extends HttpServlet{

	private static final long serialVersionUID = 1L;
	private static String tserial="";
	private static String pagepackage="com.project";
	private String charset ;
	private  Logger logger=Logger.getLogger(PageServlet.class);
	private HttpServletRequest request;

	public void init() throws ServletException
	{
		/**
		 * 加载初始化,读取配置文件
		 */
		charset = getInitParameter("charset");
		if(charset==null || "".equals(charset))
			charset="gbk";
		String config = getInitParameter("config");
		tserial=getInitParameter("tserial");
		pagepackage=getInitParameter("pagepackage");
		//加载系统框架
		logger.info("系统架构加载中....");
		new ConfigFrame(getServletContext().getRealPath("/"),config,getServletContext().getContextPath()).init();
		logger.info("系统架构加载完成.");
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response) throws
			ServletException, IOException
	{
		process(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws
			ServletException, IOException
	{
		process(request, response);
	}
	private void process(HttpServletRequest request,
						 HttpServletResponse response) throws ServletException, IOException
	{
		try{
			this.request=request;
			String pagePath=request.getRequestURI().replaceAll("\\.page", "");
			String contextPath=request.getContextPath();
			if(contextPath!=null && !"".equals(contextPath))
				pagePath=pagePath.replaceFirst(contextPath, "");

			//设置上下文
			RequestContext requestContext = new RequestContext(request, response,this);
			PageBeanUtil pageutil=new PageBeanUtil();
			PageForm pageform=requestContext.getPageForm();
			int n=pagePath.indexOf("@");
			String methodName="";//要执行的方法
			if(n!=-1){
				String urlpath=pagePath;
				pagePath=pagePath.substring(0, n);
				methodName=urlpath.substring(n+1);
			}
			if(pageform==null)
				pageform=pageutil.createPageForm(pagePath);
			String repath="";
			Class pageformCls=pageform.getClass();
			if(pageform!=null){
				//判断用户登录
				boolean loginbl=true;
				if(pageformCls.isAnnotationPresent(Login.class)){
					Login login=(Login)pageformCls.getAnnotation(Login.class);
					LoginCheck logincheck=getLoginCheck(login.type());
					if(!logincheck.checkLogin()){
						loginbl=false;
						repath=logincheck.forward(checkAjax());
					}
				}
				if(loginbl){
					try {
						pageform.init();
						//填充表单
						pageutil.fillParameter(pageform, request.getParameterMap(),request.getContentType(),charset);
						requestContext.setPageForm(pageform);
						//执行方法
						Method method = null;
						Method[] methods = pageformCls.getMethods();
						if(methodName.equals(""))methodName="execute";
						for(int i = 0; i < methods.length; i++)
						{
							if(methodName.equals(methods[i].getName()))
							{
								method = methods[i];
								break;
							}
						}
						if(method==null)throw new Exception("方法" + pageformCls.getName() + "." + methodName + "不存在");
						if(method.isAnnotationPresent(Login.class)){
							Login login=(Login)method.getAnnotation(Login.class);
							LoginCheck logincheck=getLoginCheck(login.type());
							if(!logincheck.checkLogin()){
								loginbl=false;
								repath=logincheck.forward(checkAjax());
							}
						}
						if(loginbl)repath=pageutil.execMethods(pageform, method);
					}catch(Exception ee){
						repath=getErrorRepath(pageform,ee);
					}
				}
			}
			if(repath!=null && repath.startsWith(JsonObject.JSONDATA)){
				response.setContentType("text/json;charset=utf-8");
				PrintWriter out = response.getWriter();
				out.print(repath.replaceAll(JsonObject.JSONDATA, ""));
				out.flush();
				out.close();
			}else if(repath!=null && repath.startsWith(JsonObject.HTMLDATA)){
				response.setContentType("text/html;charset=utf-8");
				PrintWriter out = response.getWriter();
				out.print(repath.replaceAll(JsonObject.HTMLDATA, ""));
				out.flush();
				out.close();
			}else{
				if(repath!=null)
					request.getRequestDispatcher(repath).forward(request,response);
			}
		}catch(Exception e){
			logger.error("页面请求错误！",e);
		}finally{
			RequestContext.clear();
		}
	}

	private LoginCheck getLoginCheck(String type) throws Exception{
		return (LoginCheck)Class.forName("com.frame.pageform.logincheck."+Character.toUpperCase(type.charAt(0)) +type.substring(1)+"LoginCheck").newInstance();
	}
	private boolean checkAjax(){
		boolean ajax ="XMLHttpRequest".equals(request.getHeader("X-Requested-With"));
		String ajaxFlag=(null==request.getParameter("ajax")?"false":request.getParameter("ajax"));
		boolean lsajax=ajax || ajaxFlag.equalsIgnoreCase("true");
		return lsajax;
	}

	private String getErrorRepath(PageForm pageform,Exception error){
		String repath="";
		String mes="";
		Class ecls=null;
		if(error.getCause()!=null){
			mes=error.getCause().getMessage();
			ecls=error.getCause().getClass();
		}else mes=error.getMessage();
		boolean islogger=true;
		if(ecls!=null && ecls ==ClientException.class)islogger=false;
		boolean lsajax=checkAjax();
		if(islogger)logger.error("页面请求发生错误！",error);
		request.setAttribute("PageServletMes",mes==null?"请求发生错误！":mes);
		repath=pageform.getErrorRepath(lsajax, error);
		return repath;
	}
	public static String getTserial(){
		return tserial;
	}
	public static String getPagepackage(){
		return pagepackage;
	}
}
